package com.example.comsys.control;

import com.example.comsys.model.Attend;
import com.example.comsys.model.AttendDepartSummary;
import com.example.comsys.model.Page;
import com.example.comsys.model.Result;
import com.example.comsys.param.AttendQueryParam;
import com.example.comsys.service.AttendService;
import com.example.comsys.util.ComSysConstant;
import com.example.comsys.util.ConvertUtils;
import com.example.comsys.util.ResultUtils;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

/**
 * so called attend control
 *
 * @author wjh
 * @date 2020/1/1, 周三
 */
@RestController
@RequestMapping(ComSysConstant.API_PREFIX + "/attend")
public class AttendController {

  @Autowired
  private AttendService attendService;

  @PostMapping("/list.json")
  public Result<Page<Attend>> queryAttends(@RequestBody AttendQueryParam queryParam) {
    Page<Attend> attendPage = attendService.queryDataByParam(queryParam);
    return ResultUtils.newSuccessfulResult(attendPage);
  }

  @GetMapping("/listByMonth.json")
  public Result<List<AttendDepartSummary>> queryAttends(int year, int month, long departId) {

    String dateStr = year + "-" + month + "-1";
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-M-dd");
    int endDay;
    try {
      endDay = getDaysOfMonth(sdf.parse(dateStr));
    } catch (ParseException e) {
      return ResultUtils.newFailedResult("日期解析出错");
    }

    // 设定此月份的起始日期和结束日期
    LocalDate startDate = LocalDate.of(year, month, 1);
    LocalDate endDate = LocalDate.of(year, month, endDay);

    AttendQueryParam queryParam = new AttendQueryParam();
    queryParam.setLimit(false);
    queryParam.setDepartId(departId);
    queryParam.setAfter(ConvertUtils.localDateToDate(startDate, true));
    queryParam.setBefore(ConvertUtils.localDateToDate(endDate, false));
    List<Attend> attendList = attendService.queryAttendsByParam(queryParam);

    if (attendList != null && attendList.size() > 0) {
      List<AttendDepartSummary> summaries = new ArrayList<>();
      Map<Integer, List<Attend>> map = attendList.stream()
          .collect(Collectors.groupingBy(v -> v.getDate().getDayOfMonth(), Collectors.toList()));

      for (int i = 1; i <= endDay; i++) {
        AttendDepartSummary summary = new AttendDepartSummary(departId);
        summary.setDate(LocalDate.of(year, month, i));
        if (map.containsKey(i)) {
          List<Attend> list = map.get(i);
          if (!CollectionUtils.isEmpty(list)) {

            // 统计本月份各项指标的数目
            list.forEach(attend -> {
              int late = attend.getLate();
              int early = attend.getLeaveEarly();
              if (late > 0) {
                if (late <= 30) {
                  summary.setLateIn030(summary.getLateIn030() + 1);
                } else {
                  summary.setLateG30(summary.getLateG30() + 1);
                }
              }
              if (early > 0) {
                if (early <= 30) {
                  summary.setEarlyIn030(summary.getEarlyIn030() + 1);
                } else {
                  summary.setEarlyG30(summary.getEarlyG30() + 1);
                }
              }
              if (attend.isIllAbsence()) {
                summary.setIllAbsence(summary.getIllAbsence() + 1);
              }
              if (attend.isThingAbsence()) {
                summary.setThingAbsence(summary.getThingAbsence() + 1);
              }
              if (attend.isPubHoliday()) {
                summary.setPubHoliday(summary.getPubHoliday() + 1);
              }
            });
          }
        }
        summaries.add(summary);
      }
      return ResultUtils.newSuccessfulResult(summaries);
    }
    return ResultUtils.newFailedResult("该部门没有该月份的考勤记录，请尽快添加");
  }


  @PostMapping("add.do")
  public Result<String> addEmployee(@RequestBody Attend attend) {

    if (attend.getEmployeeId() <= 0) {
      return ResultUtils.newFailedResult("缺少必要参数");
    }

    return attendService.addAttendRecord(attend);
  }

  @PostMapping("delete.action")
  public Result<Boolean> deleteEmployee(@RequestBody Map<String, String> args) {

    String value = args.get("attendId");
    long attendId = Long.parseLong(value);
    if (attendId <= 0) {
      return ResultUtils.newFailedResult("缺少必要参数");
    }
    boolean b = attendService.deleteAttend(attendId);

    return b ? ResultUtils.newSuccessfulResult(b) : ResultUtils.newFailedResult("删除失败");
  }


  @GetMapping("gen.action")
  public Result<String> genAttendRecord(long departId,
      @RequestParam(required = false) LocalDateTime startDate,
      @RequestParam(required = false) LocalDateTime endDate) {

    if (departId <= 0 || startDate == null) {
      return ResultUtils.newFailedResult("缺少必要参数");
    }
    if (endDate != null) {
      if (startDate.getYear() != endDate.getYear() || startDate.getMonthValue() != endDate.getMonthValue()) {
        return ResultUtils.newFailedResult("所选日期范围必须在同一年的同一个月份");
      }
    } else {
      endDate = startDate;
    }
    return attendService.batchGenerateAttendRecord(departId, startDate, endDate.getDayOfMonth());
  }

  public static int getDaysOfMonth(Date date) {
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(date);
    return calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
  }

}
